#include  <msp430x54xA.h>
#include  "Drivers.h"
#include  "..\ESS_CommonDefine.h"

unsigned int second = 0, minute = 0, hour = 0;
unsigned int year = 0, month = 0, day = 0;
char CounterFlag = false;
unsigned int HoursCount, DayCount;

void (*Counter_ptr_func)();
static void DisableCounterFunc();

#ifdef _BCD_MODE_

void setupRTC(int Year, int Month, int Day, int Hour, int Minute, int Second)
{  
  //RTCCTL01 = RTCMODE + RTCBCD + RTCHOLD + RTCTEV_1;

  RTCCTL01 = RTCBCD+RTCHOLD+RTCMODE;       // RTC enable, BCD mode,
                                            // alarm every Minute,
                                            // enable RTC interrupt

  //RTCCTL01 |= RTCTEV_0;  //Minute changed, RTCTEV_0 = Minute changed.
  RTCCTL01 |= RTCTEV_1;  //Minute changed, RTCTEV_1 = HOUR changed.
  HoursCount = 0;
  DayCount = 0;
  
  SetRTCYEAR(Year);
  SetRTCMON(Month);
  SetRTCDAY(Day);
  
  SetRTCHOUR(Hour);
  SetRTCMIN(Minute);
  SetRTCSEC(Second);  

  //SetRTCDOW(0x03);
  
  RTCCTL01 &= ~RTCHOLD;
     
  //RTCPS1CTL = RT1IP_5;                      // Interrupt freq: 2Hz  
  //RTCPS0CTL = RT0IP_7;                      // Interrupt freq: 128hz
  
  RTCCTL0 |= RTCRDYIE + RTCTEVIE;           // Enable interrupt  
}

void getClockUpdate(void)
{   	
  unsigned int hourBCD   = GetRTCHOUR(); 
  unsigned int minuteBCD = GetRTCMIN(); 
  unsigned int secondBCD = GetRTCSEC();
  
  unsigned int yearBCD = GetRTCYEAR();
  unsigned int monthBCD = GetRTCMON();
  unsigned int dayBCD = GetRTCDAY();
  unsigned int temp;
  
  second = secondBCD & 0xF0;                //high digit
  //value = 16*times - 4*times - 2 times = 10*times
  second = second - (second >> 2) - (second >> 3) + (secondBCD & 0x0F);


  minute = minuteBCD & 0xF0;                //high digit
  //value = 16*times - 4*times - 2 times = 10*times
  minute = minute - (minute >> 2) - (minute >> 3) + (minuteBCD & 0x0F);
    
  hour   = hourBCD & 0xF0;                //high digit 
  //value = 16*times - 4*times - 2 times = 10*times
  hour   = hour - (hour >> 2) - (hour >> 3) + (hourBCD & 0x0F);

  ///////////////////////////////////////////////////////////////  
  temp   = yearBCD & 0x00F0;                 
  year   = temp - (temp >> 2) - (temp >> 3) + (yearBCD & 0x0F);
  temp   = yearBCD & 0xF000;
  temp >>= 8;
  temp   = temp - (temp >> 2) - (temp >> 3) + ((yearBCD & 0x0F00)>>8);
  year = year + temp * 100;

  month = monthBCD & 0xF0;                //high digit
  //value = 16*times - 4*times - 2 times = 10*times
  month = month - (month >> 2) - (month >> 3) + (monthBCD & 0x0F);
  
  day = dayBCD & 0xF0;                //high digit
  //value = 16*times - 4*times - 2 times = 10*times
  day = day - (day >> 2) - (day >> 3) + (dayBCD & 0x0F);
   
}
unsigned int getHour(){
  return hour;
}
unsigned int getSec(){
  return second;
}
unsigned int getMin(){
  return minute;
}

unsigned int getYear(){
  return year;
}
unsigned int getMonth(){
  return month;
}
unsigned int getDay(){
  return day;
}
#else

void setupRTC(int Year, int Month, int Day, int Hour, int Minute, int Second)
{  
  //RTCCTL01 = RTCMODE + RTCBCD + RTCHOLD + RTCTEV_1;

  RTCCTL01 = RTCHOLD+RTCMODE;       // RTC enable, Binary mode,
                                            // alarm every Minute,
                                            // enable RTC interrupt

  //RTCCTL01 |= RTCTEV_0;  //Minute changed, RTCTEV_0 = Minute changed.
  RTCCTL01 |= RTCTEV_1;  //HOUR changed, RTCTEV_1 = HOUR changed.
  HoursCount = 0;
  DayCount = 0;
  
  SetRTCYEAR(Year);
  SetRTCMON(Month);
  SetRTCDAY(Day);
  
  SetRTCHOUR(Hour);
  SetRTCMIN(Minute);
  SetRTCSEC(Second);  

  //SetRTCDOW(0x03);
  
  RTCCTL01 &= ~RTCHOLD;
     
  //RTCPS1CTL = RT1IP_5;                      // Interrupt freq: 2Hz  
  //RTCPS0CTL = RT0IP_7;                      // Interrupt freq: 128hz
  
  RTCCTL0 |= RTCRDYIE + RTCTEVIE;           // Enable interrupt  
}

void getClockUpdate(void)
{   	
  hour   = GetRTCHOUR(); 
  minute = GetRTCMIN(); 
  second = GetRTCSEC();
  
  year = GetRTCYEAR();
  month = GetRTCMON();
  day = GetRTCDAY();

}
unsigned int getHour(){
  return GetRTCHOUR();
}
unsigned int getMin(){
  return GetRTCMIN();
}
unsigned int getSec(){
  return GetRTCSEC();
}

unsigned int getYear(){
  return GetRTCYEAR();
}
unsigned int getMonth(){
  return GetRTCMON();
}
unsigned int getDay(){
  return GetRTCDAY();
}
#endif

void setDailyCounterStart(void (*ptr_func)()){
  CounterFlag = true;
  Counter_ptr_func = ptr_func;
  HoursCount = 0;
}
void DisableDailyCounter(){
  CounterFlag = false;
  Counter_ptr_func = DisableCounterFunc;
  HoursCount = 0;
}

static void DisableCounterFunc(){
}
 
#pragma vector=RTC_VECTOR
__interrupt void RTC_ISR(void)
{
  switch(__even_in_range(RTCIV,16))
  {
    case 0:                           // No interrupts
      break;
    case 2:                           // RTCRDYIFG
      break;
    case 4:                           // RTCEVIFG
      //P1OUT ^= 0x03;
      if(CounterFlag){
        HoursCount++;
        if(HoursCount >= 24){
          HoursCount = 0;
          DayCount++;
          (*Counter_ptr_func)();
        }
      }
      break;
    case 6:                           // RTCAIFG
      break;
    case 8:                           // RT0PSIFG
      break;
    case 10:                          // RT1PSIFG
      break;
    case 12: break;                         // Reserved
    case 14: break;                         // Reserved
    case 16: break;                         // Reserved
    default: break;
  }
}
